<?php

namespace common\helpers;

use Yii;
use yii\helpers\BaseFileHelper;

/**
 * Class FileHelper
 * @package common\helpers
 *
 */
class FileHelper extends BaseFileHelper
{
    /**
     * 检测目录并循环创建目录
     *
     * @param $catalogue
     * @return bool
     */
    public static function mkdirs($catalogue)
    {
        if (!file_exists($catalogue)) {
            self::mkdirs(dirname($catalogue));
            mkdir($catalogue, 0777);
        }

        return true;
    }

    /**
     * 写入日志
     *
     * @param $path
     * @param $content
     * @return bool|int
     */
    public static function writeLog($path, $content)
    {
        self::mkdirs(dirname($path));
        return file_put_contents($path, "\r\n" . $content, FILE_APPEND);
    }

    /**
     * 获取文件夹大小
     *
     * @param string $dir 根文件夹路径
     * @return int
     */
    public static function getDirSize($dir)
    {
        $handle = opendir($dir);
        $sizeResult = 0;
        while (false !== ($FolderOrFile = readdir($handle))) {
            if ($FolderOrFile != "." && $FolderOrFile != "..") {
                if (is_dir("$dir/$FolderOrFile")) {
                    $sizeResult += self::getDirSize("$dir/$FolderOrFile");
                } else {
                    $sizeResult += filesize("$dir/$FolderOrFile");
                }
            }
        }

        closedir($handle);
        return $sizeResult;
    }

    /**
     * 基于数组创建目录
     *
     * @param $files
     */
    public static function createDirOrFiles($files)
    {
        foreach ($files as $key => $value) {
            if (substr($value, -1) == '/') {
                mkdir($value);
            } else {
                file_put_contents($value, '');
            }
        }
    }

    /**
     * 生成不带横杠的UUID
     *
     * @return string
     */
    public static function genUuid(){
        return sprintf('%04x%04x%04x%04x%04x%04x%04x%04x',
            // 32 bits for "time_low"
            mt_rand(0, 0xffff), mt_rand(0, 0xffff),

            // 16 bits for "time_mid"
            mt_rand(0, 0xffff),

            // 16 bits for "time_hi_and_version",
            // four most significant bits holds version number 4
            mt_rand(0, 0x0fff) | 0x4000,

            // 16 bits, 8 bits for "clk_seq_hi_res",
            // 8 bits for "clk_seq_low",
            // two most significant bits holds zero and one for variant DCE1.1
            mt_rand(0, 0x3fff) | 0x8000,

            // 48 bits for "node"
            mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
        );
    }

    /**
     * 生成文字水印图片
     * @param string $path 图片路径
     * @param string $fileName 图片名称
     * @param string $fontFile 字体路径
     * @param string $waterText 水印文字
     * @param float $fontSize 水印文字大小
     * @param float $angle 水印倾斜角度
     * @param int $alpha 水印透明度
     * @return string
     * @throws \Exception
     */
    public static function createImgWaterByText(string $file, string $fileName, string $fontFile, string $waterText, float $fontSize = 14, float $angle=45, int $alpha=20)
    {
        ob_start();

        // 检查文件和水印
        if ($fileName == "" || $waterText == "") {
            throw new \Exception('文件名为空或者水印为空');
        }
        /*** 打开图片 ***/
        // 设置输入、输出图片路径名
        //检测图片是否存在
        if (!file_exists($file)) {
            throw new \Exception('图片不存在');
        }
        // 获取图片信息
        $info = getimagesize($file);
        // 获取图片类型
        $type = image_type_to_extension($info[2],false);
        // 在内存中创建和图像类型一样的图像
        $createImageFunc = "imagecreatefrom".$type;
        // 图片复制到内存
        $image = $createImageFunc($file);

        /*** 操作图片 ***/
        // 设置字体颜色和透明度
        $color = imagecolorallocatealpha($image, 255, 255, 255, $alpha);
        // 图片宽高
        $imgWidth = $info[0];
        $imgHeight = $info[1];
        // 计算水印的宽度和高度
        $bbox = imagettfbbox($fontSize, $angle, $fontFile, $waterText);
        $waterWidth = abs($bbox[4] - $bbox[0]) + 100;
        $waterHeight = abs($bbox[5] - $bbox[1]) + 100;
        // 写入文字,铺满屏幕
        $x = 0;
        while ($x < $imgWidth) {
            $y = 0;
            while ($y < $imgHeight) {
                imagettftext($image, $fontSize, $angle, $x, $y, $color, $fontFile, $waterText);
                $y += $waterHeight;
            }
            $x += $waterWidth;
        }

        /*** 输出图片 ***/
        // 浏览器输出 保存图片的时候 需要去掉
//        header("Content-type:".$info['mime']);
        $outImageFunc = "image".$type;
        $outImageFunc($image);
        // 输出的目标文件
        $dir = Yii::getAlias('@attachment'). '/tmp/water_text/';
        is_dir($dir) === false && mkdir($dir, 0777, true);
        $fileNameArr = explode(".", $fileName);
        $resImg = $dir . $fileNameArr[0]."_water_text.".$fileNameArr[1];
        // 保存图片
        $outImageFunc($image, $resImg);
        // 销毁图片
        imagedestroy($image);
        ob_end_clean();// 清理内存中的图片输出（必须）

        return $resImg;
    }

    /**
     * 生成图片水印图片
     * @param string $path 图片路径
     * @param string $fileName 图片名称
     * @param string $waterImage 水印图片
     * @param float $angle 水印倾斜角度
     * @param int $alpha 水印透明度
     * @return string
     * @throws \Exception
     */
    public static function createImgWaterByImg(string $file, string $fileName, string $waterImage, int $alpha=80)
    {
        ob_start();

        // 检查文件和水印
        if ($file == "" || $waterImage == "") {
            throw new \Exception('文件名为空或者水印为空');
        }
        /*** 打开图片 ***/
        // 设置输入、输出图片路径名
        //检测图片是否存在
        if (!file_exists($file)) {
            throw new \Exception('图片不存在');
        }
        // 获取图片信息
        $info = getimagesize($file);
        // 获取图片类型
        $type = image_type_to_extension($info[2],false);
        // 在内存中创建和图像类型一样的图像
        $createImageFunc = "imagecreatefrom".$type;
        // 图片复制到内存
        $image = $createImageFunc($file);

        /*** 操作图片 ***/
        // 1、获取水印图片基本信息
        $waterInfo = getimagesize($waterImage);
        // 2、获取水印图片类型
        $waterType = image_type_to_extension($waterInfo[2], false);
        // 3、在内存创建图像
        $waterCreateImageFunc = "imagecreatefrom{$waterType}";
        // 4、把水印图片复制到内存中
        $water = $waterCreateImageFunc($waterImage);
        // 5、特别处理，设置透明
//        $color = imagecolorallocatealpha($water,255,255,255, 127);
//        imagefill($water,0,0, $color);
//        imagecolortransparent($water, $color);

        // 图片宽高
        $imgWidth = $info[0];
        $imgHeight = $info[1];
        // 计算水印图片的宽度和高度
        $waterWidth = $waterInfo[0];
        $waterHeight = $waterInfo[1];

        // 写入文字,铺满屏幕
        $x = 0;
        while ($x < $imgWidth) {
            $y = 0;
            while ($y < $imgHeight) {
                // 生成透明水印图
                $cut = imagecreatetruecolor($waterWidth, $waterHeight);
                // 原图坐标区块复制到新做表中
                imagecopy($cut, $image, 0, 0, $x, $y, $waterWidth, $waterHeight);
                // placing the watermark now
                imagecopy($cut, $water, 0, 0, 0, 0, $waterWidth, $waterHeight);
                // 合并图片
                imagecopymerge($image, $cut, $x, $y, 0, 0, $waterWidth, $waterHeight, $alpha);
                imagedestroy($cut);
                $y += $waterHeight;
            }
            $x += $waterWidth;
        }

        /*** 输出图片 ***/
        // 浏览器输出 保存图片的时候 需要去掉
//        header("Content-type:".$info['mime']);
        $outImageFunc = "image".$type;
        $outImageFunc($image);
        // 输出的目标文件
        $dir = Yii::getAlias('@attachment'). '/tmp/water_img/';
        is_dir($dir) === false && mkdir($dir, 0777, true);
        $fileNameArr = explode(".", $fileName);
        $resImg = $dir . $fileNameArr[0]."_water_img.".$fileNameArr[1];
        // 保存图片
        $outImageFunc($image, $resImg);
        // 销毁图片
        imagedestroy($image);
        imagedestroy($water);
        ob_end_clean();// 清理内存中的图片输出（必须）

        return $resImg;
    }
}
